package net.zui.comp;

import java.awt.Canvas;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.Insets;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import net.zui.Option;
import net.zui.inter.IGroup;
import net.zui.util.UComm;

public abstract class ZBaseFrame extends Frame implements IGroup{
	private static final long serialVersionUID = 1L;
	protected boolean change=false;
	protected int innerX,innerY,innerWidth,innerHeight;
	protected String id;
	private volatile boolean first=true;
	private Timer time;
	private Canvas canvas;
	private BufferStrategy bs;
	
	protected List<ZBase> uiList=new ArrayList<>();
	
	public ZBaseFrame(String id) throws HeadlessException {
		this(id,Option.title);
	}
	
	public ZBaseFrame(String id,String title) throws HeadlessException {
		super(title==null?Option.title:title);
		if(id==null || id.isEmpty()) {
			id=ZBase.autoId(this.getClass());
			UComm.info(this.getClass(),"BaseFrame`s id is null or empty, set new id is",id);
		}else {
			this.id=id;
		}
		setLayout(null);		
	}
	
	protected abstract void init();
	protected abstract void afterInit();
	
	@Override
	public void setVisible(boolean b) {
		super.setVisible(b);
		if(!first)return;
		first=false;
		init();		
		selfInit();
		afterInit();
	}
	
	private final void selfInit() {
		Insets insets = getInsets();
		innerWidth=getWidth()-insets.left-insets.right;
		innerHeight=getHeight()-insets.top-insets.bottom;
		UComm.info(ZBaseFrame.class, innerX,",",innerY,",",innerWidth,",",innerHeight,",");
		canvas=new Canvas();
		canvas.setSize(innerWidth, innerHeight);
		canvas.setLocation(insets.left, insets.top);
		//canvas.setBackground(Color.black);
		canvas.setIgnoreRepaint(true);
		this.add(canvas);
		canvas.requestFocus();
		canvas.createBufferStrategy(2);
		bs=canvas.getBufferStrategy();
		time=new Timer();
		time.schedule(new TimerTask() {
			@Override
			public void run() {
				Graphics2D g=null;
				g=(Graphics2D) bs.getDrawGraphics();
				g.clearRect(0, 0, innerWidth, innerHeight);
				g.setRenderingHints(Option.renderingHints);
				if(change) {
					change=false;
					Collections.sort(uiList);					
				}
				for(ZBase base:uiList) {
					base.update(g);
				}
				g.dispose();
				bs.show();
			}
		},100,100);	
		
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
	}
	
	@Override
	public void setChange() {
		change=true;
	}

	@Override
	public String add(ZBase base) {
		uiList.add(base);
		change=true;
		return base.getId();
	}

	@Override
	public List<ZBase> bases() {
		return uiList;
	}

	public String getId() {
		return id;
	}
	
	@Override
	public String toString() {
		return UComm.arrToStr("{BaseFrame}id=",id,";x,y,width,height=",getX(),",",getY(),",",getWidth(),",",getHeight());
	}

	public int getInnerX() {
		return innerX;
	}

	public void setInnerX(int innerX) {
		this.innerX = innerX;
	}

	public int getInnerY() {
		return innerY;
	}

	public void setInnerY(int innerY) {
		this.innerY = innerY;
	}

	public int getInnerWidth() {
		return innerWidth;
	}

	public void setInnerWidth(int innerWidth) {
		this.innerWidth = innerWidth;
	}

	public int getInnerHeight() {
		return innerHeight;
	}

	public void setInnerHeight(int innerHeight) {
		this.innerHeight = innerHeight;
	}
}
